#include "opencv_transform.h"

#include <iostream>
#include <opencv2\opencv.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>

using namespace std;
using namespace cv;



//基本重映射实验

void doOpencvTransform1()
{
	Mat srcImage = imread("test.jpg");

	if (!srcImage.data)
	{
		cout << "找不到这张图片！" << endl;
		return ;
	}

	imshow("Src Pic", srcImage);

	Mat dstImage, map_x, map_y;
	dstImage.create(srcImage.size(), srcImage.type());//创建和原图一样的效果图
	map_x.create(srcImage.size(), CV_32FC1);
	map_y.create(srcImage.size(), CV_32FC1);

	//遍历每一个像素点，改变map_x & map_y的值,实现翻转180度
	for (int j = 0; j < srcImage.rows; j++)
	{
		for (int i = 0; i < srcImage.cols; i++)
		{
			map_x.at<float>(j, i) = static_cast<float>(i);
			map_y.at<float>(j, i) = static_cast<float>(srcImage.rows - j);
		}
	}

	//进行重映射操作
	remap(srcImage, dstImage, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
	imshow("remap", dstImage);

	waitKey();
}



//仿射变换实验
void doOpencvTransform2()
{
	Mat src = imread("test.jpg");
	Mat dst_warp, dst_warpRotateScale;
	Point2f srcPoints[3];//原图中的三点  
	Point2f dstPoints[3];//目标图中的三点  

	//第一种仿射变换的调用方式：三点法
	//三个点对的值,上面也说了，只要知道你想要变换后图的三个点的坐标，就可以实现仿射变换  
	srcPoints[0] = Point2f(0, 0);
	srcPoints[1] = Point2f(0, src.rows - 1);
	srcPoints[2] = Point2f(src.cols - 1, 0);
	//映射后的三个坐标值
	dstPoints[0] = Point2f(0, src.rows * 0.3);
	dstPoints[1] = Point2f(src.cols * 0.25, src.rows * 0.75);
	dstPoints[2] = Point2f(src.cols * 0.75, src.rows * 0.25);

	Mat M1 = getAffineTransform(srcPoints, dstPoints);//由三个点对计算变换矩阵  
	warpAffine(src, dst_warp, M1, src.size());//仿射变换  


	//第二种仿射变换的调用方式：直接指定角度和比例										  
	//旋转加缩放  
	Point2f center(src.cols / 2, src.rows / 2);//旋转中心  
	double angle = 45;//逆时针旋转45度  
	double scale = 0.5;//缩放比例  

	Mat M2 = getRotationMatrix2D(center, angle, scale);//计算旋转加缩放的变换矩阵  
	warpAffine(dst_warp, dst_warpRotateScale, M2, src.size());//仿射变换  

	imshow("src", src);
	imshow("dst_warp1", dst_warp);
	imshow("dst_warpRotateScale2", dst_warpRotateScale);
	waitKey(0);

}



